package com.xbongbong.saas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.lfasr.util.StringUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.pro.enums.ErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.TemplateCenterErrorCodeEnum;
import com.xbongbong.pro.logistics.pojo.dto.LogisticsSaveDTO;
import com.xbongbong.pro.logistics.pojo.dto.SelectedExpressSaveDTO;
import com.xbongbong.pro.logistics.pojo.vo.LogisticsVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.ParameterConstant;
import com.xbongbong.saas.domain.entity.DataDictionaryEntity;
import com.xbongbong.saas.domain.entity.ExpressAccountEntity;
import com.xbongbong.saas.domain.entity.SelectedExpressEntity;
import com.xbongbong.saas.domain.entity.ext.ExpressAccountExt;
import com.xbongbong.saas.domain.entity.ext.SelectedExpressExt;
import com.xbongbong.saas.enums.business.ExpressCodeEnum;
import com.xbongbong.saas.enums.dictionary.DictionaryEnum;
import com.xbongbong.saas.model.DataDictionaryModel;
import com.xbongbong.saas.model.ExpressAccountModel;
import com.xbongbong.saas.model.SelectedExpressModel;
import com.xbongbong.saas.service.LogisticsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Service("logisticsService")
public class LogisticsServiceImpl implements LogisticsService {
    @Resource
    private ExpressAccountModel expressAccountModel;
    @Resource
    private SelectedExpressModel selectedExpressModel;
    @Resource
    private DataDictionaryModel dataDictionaryModel;

    /**
     * 物流查询页数据查询
     * @param baseDTO
     * @return
     * @throws XbbException
     */
    @Override
    public LogisticsVO getLogistics(BaseDTO baseDTO) throws XbbException {
        LogisticsVO logisticsVO = new LogisticsVO();
        String corpid = baseDTO.getCorpid();
        Map<String, Object> param = new HashMap<>();
        param.put(ParameterConstant.CORPID, corpid);
        param.put(ParameterConstant.DEL, BasicConstant.ZERO);
        List<ExpressAccountEntity> expressAccountEntities = expressAccountModel.findEntities(param);
        if (CollectionsUtil.isNotEmpty(expressAccountEntities)) {
            ExpressAccountExt expressAccountExt = new ExpressAccountExt();
            expressAccountExt.setDataId(expressAccountEntities.get(0).getId());
            ExpressAccountEntity expressAccountEntity = expressAccountEntities.get(0);
            BeanUtil.copyProperties(expressAccountEntity, expressAccountExt);
            logisticsVO.setExpressAccountExt(expressAccountExt);
        }

        List<SelectedExpressEntity> selectedExpressEntities = selectedExpressModel.findEntities(param);
        List<SelectedExpressExt> selectedExpressExtList = new ArrayList<>();
        if (CollectionsUtil.isNotEmpty(selectedExpressEntities)) {
            for (SelectedExpressEntity selectedExpressEntity : selectedExpressEntities) {
                SelectedExpressExt selectedExpressExt = new SelectedExpressExt();
                selectedExpressExt.setDataId(selectedExpressEntity.getId());
                selectedExpressExt.setExpressName(selectedExpressEntity.getExpressName());
                selectedExpressExt.setExpressCode(selectedExpressEntity.getExpressCode());
                selectedExpressExt.setAddTime(selectedExpressEntity.getAddTime());
                selectedExpressExt.setUpdateTime(selectedExpressEntity.getUpdateTime());
                selectedExpressExtList.add(selectedExpressExt);
            }
        }
        logisticsVO.setSelectedLogisticsList(selectedExpressExtList);
        Map<String, String> expressCodeMap = ExpressCodeEnum.getAllEnum();
        logisticsVO.setExpressCodeMap(expressCodeMap);
        return logisticsVO;
    }

    /**
     * 物流查询页数据保存
     * @param logisticsSaveDTO
     * @return
     * @throws XbbException
     */
    @Override
    public LogisticsVO saveLogistics(LogisticsSaveDTO logisticsSaveDTO) throws XbbException {
        String corpid = logisticsSaveDTO.getCorpid();
        String userId = logisticsSaveDTO.getUserId();
        ExpressAccountExt expressAccountExt = logisticsSaveDTO.getExpressAccountExt();
        //快递100账号信息
        Long expressAccountId = expressAccountExt.getDataId();
        String accountKey = expressAccountExt.getAccountKey();
        String secret = expressAccountExt.getSecret();
        String customer = expressAccountExt.getCustomer();
        if (StringUtil.isEmpty(accountKey) || StringUtil.isEmpty(secret) || StringUtil.isEmpty(customer)
            || accountKey.length() > 100 || secret.length() > 100 || customer.length() > 100) {
            throw new XbbException(TemplateCenterErrorCodeEnum.API_ERROR_402007);
        }

        ExpressAccountEntity expressAccountEntity = new ExpressAccountEntity();
        expressAccountEntity.setCorpid(corpid);
        expressAccountEntity.setCreatorId(userId);
        expressAccountEntity.setAccountKey(accountKey);
        expressAccountEntity.setSecret(secret);
        expressAccountEntity.setCustomer(customer);
        expressAccountEntity.setAddTime(DateTimeUtil.getInt());
        expressAccountEntity.setUpdateTime(DateTimeUtil.getInt());
        expressAccountEntity.setDel(BasicConstant.ZERO);
        //新建
        if (Objects.isNull(expressAccountId) || Objects.equals(expressAccountId, 0L)){
            expressAccountModel.insert(expressAccountEntity);
        }else {
            //编辑更新
            expressAccountEntity.setId(expressAccountId);
            expressAccountModel.update(expressAccountEntity);
        }

        //已选快递公司list
        List<SelectedExpressSaveDTO> selectedExpressSaveDTOList = logisticsSaveDTO.getSelectedExpressSaveDTOList();
        //当前已选的所有快递公司
        Map<String, Object> param = new HashMap<>();
        param.put(ParameterConstant.CORPID, corpid);
        List<SelectedExpressEntity> entities = selectedExpressModel.findEntities(param);
        Map<String, SelectedExpressEntity> selectedExpressEntityMap = new HashMap<>(entities.size());
        entities.forEach(item -> selectedExpressEntityMap.put(item.getExpressName(), item));
        List<SelectedExpressEntity> insertList = new ArrayList<>();
        List<SelectedExpressEntity> updateList = new ArrayList<>();
        for (SelectedExpressSaveDTO selectedExpressSaveDTO : selectedExpressSaveDTOList) {
            if (selectedExpressEntityMap.containsKey(selectedExpressSaveDTO.getExpressName())) {
                SelectedExpressEntity selectedExpressEntity = selectedExpressEntityMap.get(selectedExpressSaveDTO.getExpressName());
                if (Objects.equals(selectedExpressEntity.getDel(), 1)) {
                    selectedExpressEntity.setDel(0);
                    updateList.add(selectedExpressEntity);
                }
                selectedExpressEntityMap.remove(selectedExpressSaveDTO.getExpressName());
            } else {
                SelectedExpressEntity selectedExpressEntity = new SelectedExpressEntity();
                selectedExpressEntity.setCorpid(corpid);
                selectedExpressEntity.setCreatorId(userId);
                selectedExpressEntity.setExpressName(selectedExpressSaveDTO.getExpressName());
                selectedExpressEntity.setExpressCode(selectedExpressSaveDTO.getExpressCode());
                selectedExpressEntity.setAddTime(DateTimeUtil.getInt());
                selectedExpressEntity.setUpdateTime(DateTimeUtil.getInt());
                selectedExpressEntity.setDel(BasicConstant.ZERO);
                insertList.add(selectedExpressEntity);
            }
        }

        List<Long> updateDelIdList = new ArrayList<>();
        selectedExpressEntityMap.forEach((key, value) -> {
            if (Objects.equals(value.getDel(), 0)) {
                updateDelIdList.add(value.getId());
            }
        });
        if (!updateDelIdList.isEmpty()){
            selectedExpressModel.updateBatchToDel(updateDelIdList,corpid);
        }
        if (!insertList.isEmpty()){
            selectedExpressModel.insertBatch(insertList);
        }
        if (!updateList.isEmpty()){
            selectedExpressModel.updateBatch(updateList,corpid);
        }
        // 已选值同步到数据字典中 TODO 可抽取新方法
        if (CollectionsUtil.isNotEmpty(selectedExpressSaveDTOList)) {
            Map<String, String> selectMap = new HashMap<>(selectedExpressSaveDTOList.size());
            selectedExpressSaveDTOList.forEach(item -> selectMap.put(item.getExpressCode(), item.getExpressName()));
            DataDictionaryEntity dataDictionaryEntity = dataDictionaryModel.getByType(DictionaryEnum.EXPRESS_NAME.getType(), corpid);
            if (Objects.isNull(dataDictionaryEntity)) {
                JSONArray insertArr = new JSONArray();
                selectMap.forEach((key, value) -> {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("text", value);
                    jsonObject.put("value", key);
                    jsonObject.put("enable", 1);
                    jsonObject.put("isEdit", 0);
                    insertArr.add(jsonObject);
                });
                DataDictionaryEntity dictionaryEntity = new DataDictionaryEntity();
                dictionaryEntity.setCorpid(corpid);
                dictionaryEntity.setType(DictionaryEnum.EXPRESS_NAME.getType());
                dictionaryEntity.setData(JSON.toJSONString(insertArr));
                dataDictionaryModel.insert(dictionaryEntity);
            } else {
                JSONArray jsonArray = JSON.parseArray(dataDictionaryEntity.getData());
                for (int i = 0; i < jsonArray.size(); i++) {
                    JSONObject jsonObject = jsonArray.getJSONObject(i);
                    selectMap.remove(jsonObject.getString("value"));
                }
                if (!selectMap.isEmpty()) {
                    JSONArray insertArr = new JSONArray();
                    selectMap.forEach((key, value) -> {
                        JSONObject jsonObject = new JSONObject();
                        jsonObject.put("text", value);
                        jsonObject.put("value", key);
                        jsonObject.put("enable", 1);
                        jsonObject.put("isEdit", 0);
                        insertArr.add(jsonObject);
                    });
                    jsonArray.addAll(insertArr);
                    dataDictionaryModel.update(dataDictionaryEntity.getId(), corpid, JSON.toJSONString(jsonArray));
                }
            }
        }
        return null;
    }
}
